--[[
	File: sv_networking.lua
	For: FTS: Stronghold
	By: Ultra

	label each file network set
]]--

GM.Net = {}

util.AddNetworkString "sh_maplist"
util.AddNetworkString "sh_winningmap"
util.AddNetworkString "sh_teamcreated"
util.AddNetworkString "sh_teamdisbanded"
util.AddNetworkString "sh_teamleaderchange"
util.AddNetworkString "sh_countdown"
util.AddNetworkString "sh_cancelcountdown"
util.AddNetworkString "PlayerSounds_PlayerDeath"
util.AddNetworkString "PlayerSounds_ScalePlayerDamage"
util.AddNetworkString "sh_statistics"
util.AddNetworkString "sh_moneyandmultiplier"
util.AddNetworkString "sh_hat"
util.AddNetworkString "sh_advert"
util.AddNetworkString "sh_gameover"
util.AddNetworkString "sh_spawned"
util.AddNetworkString "sh_spawnprotection"
util.AddNetworkString "sh_killed"
util.AddNetworkString "sh_hitdetection"
util.AddNetworkString "sh_loadouts"
util.AddNetworkString "sh_loadout"
util.AddNetworkString "sh_faderagdoll"
util.AddNetworkString "sh_items"
util.AddNetworkString "sh_item"
util.AddNetworkString "sh_licenses"
util.AddNetworkString "sh_license"
util.AddNetworkString "sh_flashed"

--[[ voting.lua ]]--

--for _, v in ipairs( player.GetAll() ) do
--	datastream.StreamToClients( v, "sh_maplist", GAMEMODE.MapList )
--end
function GM.Net:BroadcastMapList( tblMapList )
	net.Start( "sh_maplist" )
		net.WriteTable( tblMapList )
	net.Broadcast()
end

-- local rf = RecipientFilter()
-- rf:AddAllPlayers()
-- umsg.Start( "sh_winningmap", rf )
	-- umsg.String( GAMEMODE.WinningMap )
-- umsg.End()
function GM.Net:SendWinningMap( strMap )
	net.Start( "sh_winningmap" )
		net.WriteString( strMap )
	net.Broadcast()
end


--[[ teams.lua ]]--

-- umsg.Start( "sh_teamcreated", ply )
-- 	umsg.Short( index )
-- 	umsg.Entity( leader )
-- 	umsg.String( name )
-- 	umsg.Short( color.r )
-- 	umsg.Short( color.g )
-- 	umsg.Short( color.b )
-- umsg.End()
function GM.Net:SendTeamToClient( pPlayer, intIndex, pLeader, strName, colColor )
	net.Start( "sh_teamcreated" )
		net.WriteInt( intIndex, 16 )
		net.WriteEntity( pLeader )
		net.WriteString( strName )
		net.WriteUInt( colColor.r, 8 )
		net.WriteUInt( colColor.g, 8 )
		net.WriteUInt( colColor.b, 8 )
	net.Send( pPlayer )
end

-- local rf = RecipientFilter()
-- rf:AddAllPlayers()
-- umsg.Start( "sh_teamdisbanded", rf )
-- 	umsg.Short( index )
-- umsg.End()
function GM.Net:SendDisbandToClients( intIndex )
	net.Start( "sh_teamdisbanded" )
		net.WriteInt( intIndex, 16 )
	net.Broadcast()
end

-- local rf = RecipientFilter()
-- rf:AddAllPlayers()
-- umsg.Start( "sh_teamleaderchange", rf )
-- 	umsg.Short( index )
-- 	umsg.Entity( leader )
-- umsg.End()
function GM.Net:SendLeaderToClients( intIndex, pleader )
	net.Start( "sh_teamleaderchange" )
		net.WriteInt( intIndex, 16 )
		net.WriteEntity( pleader )
	net.Broadcast()
end


--[[ shared.lua ]]--

-- local rf = rf
-- if !rf then
-- 	rf = RecipientFilter()
-- 	rf:AddAllPlayers()
-- end
-- umsg.Start( "sh_countdown", rf )
--   umsg.Short( length or 0 )
--   umsg.String( title or "" )
--   umsg.String( lua_cl )
-- umsg.End()
function GM.Net:BroadcastCountdown( intLen, strTitle, strLuaCL )
	net.Start( "sh_countdown" )
		net.WriteInt( intLen, 32 )
		net.WriteString( strTitle )
		net.WriteString( strLuaCL )
	net.Broadcast()
end	
	
-- local rf = RecipientFilter()
-- rf:AddAllPlayers()
-- umsg.Start( "sh_cancelcountdown", rf )
-- umsg.End()
function GM.Net:BroadcastCancelCountdown()
	net.Start( "sh_cancelcountdown" )
	net.Broadcast()
end


--[[ playersounds.lua ]]--

-- umsg.Start( "PlayerSounds_PlayerDeath", v )
-- umsg.Entity( ply )
-- umsg.String( ply:GetModel() )
-- umsg.End()
function GM.Net:PlayerSoundsDeath( pl, pPlayer )
	net.Start( "PlayerSounds_PlayerDeath" )
		net.WriteEntity( pPlayer )
		net.WriteString( pPlayer:GetModel() )
	net.Send( pl )
end

-- umsg.Start( "PlayerSounds_ScalePlayerDamage", v )
-- umsg.Entity( ply )
-- umsg.String( ply:GetModel() )
-- umsg.Bool( ply.LastHurtHead or false )
-- umsg.End()
function GM.Net:PlayerSoundsScalePlayerDamage( pl, pPlayer )
	net.Start( "PlayerSounds_ScalePlayerDamage" )
		net.WriteEntity( pPlayer )
		net.WriteString( pPlayer:GetModel() )
		net.WriteBit( pPlayer.LastHurtHead and true or false )
	net.Send( pl )
end


--[[ player_extension.lua ]]--

-- datastream.StreamToClients( ply, "sh_statistics", {ply=self,tbl=self.Statistics} )
function GM.Net:SendClientStats( pl, pPlayer )
	net.Start( "sh_statistics" )
		net.WriteEntity( pPlayer )
		net.WriteTable( pPlayer.Statistics )
	net.Send( pl )
end

-- function meta:SendMoneyAndMultiplier()
-- 	umsg.Start( "sh_moneyandmultiplier", self )
-- 		umsg.Float( self.Money or 0 )
-- 		umsg.Float( self.Multiplier or 0 )
-- 	umsg.End()
-- end
function GM.Net:SendMoneyAndMultiplier( pPlayer )
	net.Start( "sh_moneyandmultiplier" )
		net.WriteFloat( pPlayer.Money or 0 )
		net.WriteFloat( pPlayer.Multiplier or 0 )
	net.Send( pPlayer )
end

-- function meta:EnableHat( name )
-- 	local rf = RecipientFilter()
-- 	rf:AddAllPlayers()
	
-- 	umsg.Start( "sh_hat", rf )
-- 		umsg.Entity( self )
-- 		if !name or name == "" then
-- 			umsg.Bool( false )
-- 		else
-- 			umsg.Bool( true )
-- 			umsg.String( name )
-- 		end
-- 	umsg.End()
-- end
function GM.Net:EnableHat( pPlayer, strHatName ) --does this sync with new players right?
	net.Start( "sh_hat" )
		net.WriteEntity( pPlayer )

		if not strHatName or strHatName == "" then
			net.WriteBit( false )
		else
			net.WriteBit( true )
			net.WriteString( strHatName )
		end
	net.Broadcast()
end


--[[ player.lua ]]--

-- umsg.Start( "sh_advert", ply )
-- 	umsg.Short( (GAMEMODE.Adverts[GAMEMODE.CurrentAdvert] and GAMEMODE.Adverts[GAMEMODE.CurrentAdvert].color) or 1 )
-- 	local str = (GAMEMODE.Adverts[GAMEMODE.CurrentAdvert] and GAMEMODE.Adverts[GAMEMODE.CurrentAdvert].text) or ""
-- 	for k, v in pairs(GAMEMODE.KeyReplacements) do str = string.gsub( str, k, tostring(v()) ) end
-- 	umsg.String( str )
-- umsg.End()
function GM.Net:SendAdvert( pPlayer )
	net.Start( "sh_advert" )
		net.WriteInt( (GAMEMODE.Adverts[GAMEMODE.CurrentAdvert] and GAMEMODE.Adverts[GAMEMODE.CurrentAdvert].color) or 1, 8 )

		local str = (GAMEMODE.Adverts[GAMEMODE.CurrentAdvert] and GAMEMODE.Adverts[GAMEMODE.CurrentAdvert].text) or ""
		for k, v in pairs( GAMEMODE.KeyReplacements ) do
			str = string.gsub( str, k, tostring(v()) )
		end

		net.WriteString( str )
	net.Send( pPlayer )
end

-- umsg.Start( "sh_gameover", ply )
--   umsg.Short( self.GameOverTeam )
--   umsg.Short( self.GameOverWinner )
-- umsg.End()
function GM.Net:SendGameOver( pPlayer )
	net.Start( "sh_gameover" )
		net.WriteInt( GAMEMODE.GameOverTeam or 0, 16 )
		net.WriteInt( GAMEMODE.GameOverWinner or 0, 16 )
	net.Send( pPlayer )
end

-- umsg.Start( "sh_spawned", ply )
-- umsg.End()
function GM.Net:SendPlayerSpawned( pPlayer )
	net.Start( "sh_spawned" )
	net.Send( pPlayer )
end

-- umsg.Start( "sh_spawnprotection", ply )
--   umsg.Bool( false )
-- umsg.End()
--
-- umsg.Start( "sh_spawnprotection", ply )
--   umsg.Bool( true )
-- umsg.End()
function GM.Net:SendSpawnProtection( pPlayer, bProt )
	net.Start( "sh_spawnprotection" )
		net.WriteBit( bProt and true or false )
	net.Send( pPlayer )
end

-- umsg.Start( "sh_killed", ply )
-- 	umsg.Entity( killer )
-- umsg.End()
function GM.Net:SendPlayerKilled( pPlayer, pKiller )
	net.Start( "sh_killed" )
		net.WriteEntity( pKiller )
	net.Send( pPlayer )
end

-- umsg.Start( "sh_hitdetection", attacker )
-- umsg.End()
function GM.Net:SendHitDetect( pPlayer )
	net.Start( "sh_hitdetection" )
	net.Send( pPlayer )
end


--[[ loadout.lua ]]--

-- datastream.StreamToClients( ply, "sh_loadouts", loadouts )
function GM.Net:SendClientLoadouts( pPlayer )
	if not IsValid( pPlayer ) then return end

	local loadouts = pPlayer:GetLoadouts()
	if not loadouts then return end

	net.Start( "sh_loadouts" )
		net.WriteTable( loadouts )
	net.Send( pPlayer )	
end

-- datastream.StreamToClients( ply, "sh_loadout", {[name]=loadout} )
function GM.Net:SendClientLoadout( pPlayer, strName )
	if not IsValid( pPlayer ) then return end

	local loadout = pPlayer:GetLoadout( strName )
	if not loadout then return end

	net.Start( "sh_loadout" )
		net.WriteTable{ [strName] = loadout }
	net.Send( pPlayer )
end


--[[ init.lua ]]--

-- local rf = RecipientFilter()
-- rf:AddAllPlayers()
-- umsg.Start( "sh_faderagdoll", rf )
-- 	umsg.Entity( tbl.ent )
-- umsg.End()
function GM.Net:BroadcastFadeRagdoll( eRagdoll )
	net.Start( "sh_faderagdoll" )
		net.WriteEntity( eRagdoll )
	net.Broadcast()
end

-- local rf = RecipientFilter()
-- rf:AddAllPlayers()
-- umsg.Start( "sh_gameover", rf )
--   umsg.Short( team_index )
--   umsg.Short( winner )
-- umsg.End()
function GM.Net:BroadcastGameOver( intTeamIndex, intWinner )
	net.Start( "sh_gameover" )
		net.WriteInt( intTeamIndex or 0, 16 )
		net.WriteInt( intWinner or 0, 16 )
	net.Broadcast()
end


--[[ gbux.lua ]]--

-- function SH_SendClientItems( ply )
-- 	if !IsValid( ply ) then return end

-- 	local items = ply:GetItems()
-- 	if !items then return end
	
-- 	datastream.StreamToClients( ply, "sh_items", items )
-- end
function GM.Net:SendClientItems( pPlayer )
	local items = pPlayer:GetItems()
	if not items then return end

	net.Start( "sh_items" )
		net.WriteTable( items )
	net.Send( pPlayer )
end

-- function SH_SendClientItem( ply, name )
-- 	if !IsValid( ply ) then return end

-- 	local item = ply:GetItem( name )
-- 	if !item then return end
	
-- 	datastream.StreamToClients( ply, "sh_item", {[name]=item} )
-- end
function GM.Net:SendClientItem( pPlayer, strName )
	local item = pPlayer:GetItem( strName )
	if not item then return end

	net.Start( "sh_item" )
		net.WriteTable{ [strName] = item }
	net.Send( pPlayer )
end

-- function SH_SendClientLicenses( ply )
-- 	if !IsValid( ply ) then return end

-- 	local licenses = ply:GetLicenses()
-- 	if !licenses then return end
	
-- 	datastream.StreamToClients( ply, "sh_licenses", licenses )
-- end
function GM.Net:SendClientLicenses( pPlayer )
	if not IsValid( pPlayer ) then return end

	local licenses = pPlayer:GetLicenses()
	if not licenses then return end

	net.Start( "sh_licenses" )
		net.WriteTable( licenses )
	net.Send( pPlayer )
end

-- function SH_SendClientLicense( ply, type, class )
-- 	if !IsValid( ply ) then return end

-- 	local license = ply:GetLicense( type, class )
-- 	if !license then return end
	
-- 	--ErrorNoHalt( "Sending "..type.." "..class.."\n" )
-- 	datastream.StreamToClients( ply, "sh_license", {[type]={[class]=license}} )
-- end
function GM.Net:SendClientLicense( pPlayer, strType, strClass )
	if not IsValid( pPlayer ) then return end

	local license = pPlayer:GetLicense( strType, strClass )
	if not license then return end

	net.Start( "sh_license" )
		net.WriteTable{ [strType] = {[strClass] = license} }
	net.Send( pPlayer )
end